package com.zhaotianhao.servicecart.service.impl;

import com.zhaotianhao.servicecart.api.ProductApi;
import com.zhaotianhao.servicecart.api.SkuStockApi;
import com.zhaotianhao.servicecart.dto.CartDto;
import com.zhaotianhao.servicecart.dto.SkuStockDto;
import com.zhaotianhao.servicecart.service.CartService;
import com.zhaotianhao.servicecart.vo.CartVo;
import com.zhaotianhao.servicecart.vo.SkuVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * @Author Z-7
 * @Date 2022/4/28
 */
@Slf4j
@Service
public class CartServiceImpl implements CartService {
    @Autowired
    private SkuStockApi skuStockApi;
    @Autowired
    private ProductApi productApi;
    @Resource
    private RedisTemplate redisTemplate;
    private String cacheKey = "mycart:%s";

    /**
     * 加购 方法针对 页面按钮
     * <点击加入购物次> 点击一次 加一次
     * @param cartDto
     * @return
     */
    @Override
    public Boolean editCart(CartDto cartDto) {
        String redisKey = String.format(cacheKey,cartDto.getUserId());

        if (!redisTemplate.opsForHash().hasKey(redisKey,cartDto.getSkuId())) {
            // redis中没有
            redisTemplate.opsForHash().put(redisKey,cartDto.getSkuId(),cartDto.getNumber());
            // 获取购物车中的数量
            Long number = getNumber(redisKey, cartDto.getSkuId());
            changeOccupyStock(cartDto.getSkuId(),number);
            return true;
        }
        // 自增
        redisTemplate.opsForHash().increment(redisKey,cartDto.getSkuId(),cartDto.getNumber());
        // 获取购物车中的数量
        Long number = getNumber(redisKey, cartDto.getSkuId());
        changeOccupyStock(cartDto.getSkuId(),number);
        return true;
    }

    /**
     * 修改库存
     * @param skuId
     * @param number
     */
    public void changeOccupyStock(Long skuId,Long number) {
        SkuStockDto skuStockDto = new SkuStockDto();
        skuStockDto.setSkuId(skuId);
        skuStockDto.setOccupyStock(number);
        skuStockApi.updateOccupyStock(skuStockDto);
    }

    /**
     * 获取redis商品购买数量
     * @return
     */
    public Long getNumber(String redisKey,Long hashKey){
        Object o = redisTemplate.opsForHash().get(redisKey, hashKey);
        return Long.parseLong(o.toString());
    }

    /**
     * 我的购物车
     * @param userId
     * @return
     */
    @Override
    public CartVo getMyCart(long userId) {
        String redisKey = String.format(cacheKey,userId);
        // 获取购物车中hash值 所有的key
        Set keys = redisTemplate.opsForHash().keys(redisKey);
        ArrayList keyList = new ArrayList(keys);
        ArrayList<Long> skuIds = new ArrayList<>();
        keyList.forEach(id -> {
            skuIds.add(Long.parseLong(id.toString()));
        });
        CartDto cartDto = new CartDto();
        cartDto.setSkuIds(skuIds);
        // 远程调用 获取购物车详情
        List<SkuVo> skuVos = productApi.getCartSkuInfoByIds(cartDto);
        // 获取购物车中hash值 所有的购买数量
        List values = redisTemplate.opsForHash().values(redisKey);
        Long total = 0L;
        for (int i = 0; i < values.size(); i++) {
            SkuVo skuVo = skuVos.get(i);
            skuVo.setPrice(skuVo.getPrice() / 100);
            Long skuPrice =skuVo.getPrice()  * Long.parseLong(values.get(i).toString());
            total += skuPrice;
            skuVo.setTotal(skuPrice);
            skuVo.setNumber(Long.parseLong(values.get(i).toString()));
        }
        CartVo cartVo = new CartVo();
        cartVo.setTotal(total).setSkuVoList(skuVos);
        return cartVo;
    }

    /**
     * 修改购物车
     *
     * @param cartDto
     * @return
     */
    @Override
    public Boolean changeCart(CartDto cartDto) {
        String redisKey = String.format(cacheKey,cartDto.getUserId());
        if (cartDto.getNumber() == 0) {
            // 修改为0 即 删除
            Boolean result = deleteBySkuId(cartDto.getUserId(), cartDto.getSkuId());
            changeOccupyStock(cartDto.getSkuId(), 0L);
            return result;
        }
        // 否则 修改库存
        redisTemplate.opsForHash().put(redisKey,cartDto.getSkuId(),cartDto.getNumber());
        changeOccupyStock(cartDto.getSkuId(), cartDto.getNumber());
        return true;
    }

    /**
     * 删除
     *
     * @param userId
     * @param skuId
     * @return
     */
    @Override
    public Boolean deleteBySkuId(Long userId, Long skuId) {
        String redisKey = String.format(cacheKey,userId);
        Long result = redisTemplate.opsForHash().delete(redisKey, skuId);
        changeOccupyStock(skuId, 0L);
        return result > 0;
    }

    /**
     * 下单操作 删除购物车
     *
     * @param userId
     * @param skuIds
     * @return
     */
    @Override
    public Boolean deleteBySkuIds(long userId, List<Long> skuIds) {
        String redisKey = String.format(cacheKey,userId);
        for (Long skuId : skuIds) {
            Long result = redisTemplate.opsForHash().delete(redisKey, skuId);
            changeOccupyStock(skuId, 0L);
        }
        return true;
    }

}
